package com.ruicar.afs.cloud.apply.contract.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruicar.afs.cloud.apply.business.service.ApplySignRelationService;
import com.ruicar.afs.cloud.apply.common.entity.ApplyContractInfo;
import com.ruicar.afs.cloud.apply.common.entity.ApplyCustBaseInfo;
import com.ruicar.afs.cloud.apply.common.entity.ApplyOrderInfo;
import com.ruicar.afs.cloud.apply.common.entity.ApplySignRelation;
import com.ruicar.afs.cloud.apply.contract.condition.AttachmentListCondition;
import com.ruicar.afs.cloud.apply.contract.condition.ComAttachmentCondition;
import com.ruicar.afs.cloud.apply.contract.service.ApplyContractInfoService;
import com.ruicar.afs.cloud.apply.contract.service.CreatContractService;
import com.ruicar.afs.cloud.apply.pre.loan.service.ApplyCustBaseInfoService;
import com.ruicar.afs.cloud.apply.pre.loan.service.ApplyOrderInfoService;
import com.ruicar.afs.cloud.bizcommon.print.entity.ComPrintFormManage;
import com.ruicar.afs.cloud.bizcommon.print.service.ComPrintFormManageService;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.image.condition.ImageCondition;
import com.ruicar.afs.cloud.image.config.FileProperties;
import com.ruicar.afs.cloud.image.entity.ComAttachmentFile;
import com.ruicar.afs.cloud.image.service.ComAttachmentFileService;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.util.*;

import static com.ruicar.afs.cloud.apply.common.utils.ApplyConstants.*;

/**
 * 影像件controller
 *
 * @author 耿继辉
 */
@RestController
@AllArgsConstructor
@RequestMapping("/applyComAttach")
@Slf4j
@ApiOperation("影像件管理")
public class ComAttachmentFileController {

    private final ComAttachmentFileService comAttachmentFileService;
    private final CreatContractService creatContractService;
    private FileProperties fileProperties;
    private final ApplySignRelationService applySignRelationService;
    private final ComAttachmentFileService attachmentFileService;
    private final ApplyOrderInfoService applyOrderInfoService;
    private final ApplyCustBaseInfoService applyCustBaseInfoService;
    private ApplyContractInfoService applyContractInfoService;
    private final ComPrintFormManageService comPrintFormManageService;
    /**
     * 根据场景取最新合同模板
     * @param condition
     * @return
     */
    @PostMapping("/getComAttachForContract")
    public IResponse<IPage<List<ComAttachmentFile>>> getComAttachForContract(@RequestBody ImageCondition condition) {

        Page page = new Page(condition.getPageNumber(), condition.getPageSize());
        IPage<List<ComAttachmentFile>> listIPage = comAttachmentFileService.getComAttachMentFileByPage(page,condition);
        return IResponse.success(listIPage);
    }

    /**
     * 根据业务编号查询所有合同模板
     * @param condition
     * @return
     */
    @PostMapping("/getComAttach")
    public IResponse getComAttach(@RequestBody ComAttachmentCondition condition) {

        List<ComAttachmentFile> list = comAttachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                .eq(StringUtil.isNotEmpty(condition.getBusiNo()), ComAttachmentFile::getBusiNo, condition.getBusiNo())
                .like(ComAttachmentFile::getFileType,"PDF"));
        return IResponse.success(list);
    }

    /**
     * 放款申请-批量模板生成
     *
     * @param condition
     * @return
     */
    @PostMapping("/contractBatchPrint")
    @Transactional(rollbackFor = Exception.class)
    public IResponse contractBatchPrint(@RequestBody ComAttachmentCondition condition) {

        List<ComAttachmentFile> fileList = creatContractService.contractBatchPrint(condition.getApplyNo(),condition.getContractNo(),condition.getServiceClientType());
        ApplyContractInfo contractInfo = applyContractInfoService.getOne(Wrappers.<ApplyContractInfo>query().lambda()
                .eq(ApplyContractInfo::getApplyNo, condition.getApplyNo()));
        if(contractInfo !=null){
            //放款合同生成完成之后更新合同表重出表识为：否
            contractInfo.setReappearFlag(NO);
            applyContractInfoService.updateById(contractInfo);
        }
        return IResponse.success(fileList);
    }

    /**
     * 放款申请-单个模板生成
     * @param condition
     * @return
     */
    @PostMapping("contractSinglePrint")
    @Transactional(rollbackFor = Exception.class)
    public IResponse contractSinglePrint(@RequestBody ComAttachmentCondition condition){

        ComAttachmentFile attachmentFile = comAttachmentFileService.getById(condition.getId());
        Assert.isTrue(attachmentFile!=null,"重出合同模板不存在");
        ComAttachmentFile comAttachmentFile = creatContractService.contractSinglePrint(condition.getApplyNo(),attachmentFile.getBusiNo(),attachmentFile,condition.getServiceClientType());
        return IResponse.success(comAttachmentFile);
    }

    /**
     * 进件申请-批量模板生成
     *
     * @param condition
     * @return
     */
    @PostMapping("/applyBatchPrint")
    @Transactional(rollbackFor = Exception.class)
    public IResponse applyBatchPrint(@RequestBody ComAttachmentCondition condition) {

        List<ComAttachmentFile> fileList = creatContractService.applyBatchPrint(condition.getApplyNo(),condition.getServiceClientType());
        return IResponse.success(fileList);
    }

    /**
     * 进件申请-单个模板重出
     * @param condition
     * @return
     */
    @PostMapping("/applySinglePrint")
    @Transactional(rollbackFor = Exception.class)
    public IResponse applySinglePrint(@RequestBody ComAttachmentCondition condition){

        ComAttachmentFile attachmentFile = comAttachmentFileService.getById(condition.getId());
        Assert.isTrue(attachmentFile!=null,"重出合同模板不存在");
        ComAttachmentFile comAttachmentFile = creatContractService.applySinglePrint(attachmentFile.getBusiNo(),attachmentFile,condition.getServiceClientType());
        return IResponse.success(comAttachmentFile);
    }

    /**
     * 进件申请-根据申请编号、客户id单个模板重出
     * @param condition
     * @return
     */
    @PostMapping("/applySinglePrintByCustId")
    @Transactional(rollbackFor = Exception.class)
    public IResponse applySinglePrintByCustId(@RequestBody ComAttachmentCondition condition){
        if(condition.getCustId() ==null){
            return IResponse.fail("客户id不能为空");
        }
        if(StrUtil.isBlank(condition.getApplyNo())){
            return IResponse.fail("申请编号不能为空");
        }
        List<ApplySignRelation> signRelationList = applySignRelationService.list(Wrappers.<ApplySignRelation>query().lambda()
                .eq(ApplySignRelation::getCustId, condition.getCustId())
                .eq(ApplySignRelation::getBusinessNo,condition.getApplyNo()));
        if(signRelationList !=null && signRelationList.size()>0){
            for(ApplySignRelation relation:signRelationList){
                List<ComAttachmentFile> comAttachmentFileList = attachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                        .eq(ComAttachmentFile::getBusiNo, condition.getApplyNo())
                        .eq(ComAttachmentFile::getAttachmentCode,relation.getTempleId().toString()));
                if(comAttachmentFileList !=null && comAttachmentFileList.size()>0){
                    for(ComAttachmentFile file :comAttachmentFileList){
                        Assert.isTrue(file!=null,"重出合同模板不存在");
                        creatContractService.applySinglePrintByCustId(file.getBusiNo(),file,condition.getServiceClientType());
                    }
                }
                relation.setStatus(NO);
                relation.setUpdateTime(null);
                applySignRelationService.updateById(relation);
            }
        }else{
            return IResponse.fail("合同签约数据不存在，无法重出");
        }
        return IResponse.success("重出成功！！");
    }

    /**
     * 重出所有合同
     * @param condition
     * @return
     */
    @PostMapping("/singlePrintAll")
    @Transactional(rollbackFor = Exception.class)
    public IResponse singlePrintAll(@RequestBody ComAttachmentCondition condition){
        if(StrUtil.isBlank(condition.getBusiNo())){
            return IResponse.fail("重出编号不能为空");
        }
        if(StrUtil.isBlank(condition.getApplyNo())){
            return IResponse.fail("申请编号不能为空");
        }
        if(StrUtil.isBlank(condition.getOutScene())){
            return IResponse.fail("重出场景不能为空");
        }
        List<ApplySignRelation> signRelationList = null;
        if(OUT_SCENE_TWO.equals(condition.getOutScene())){
            //重出场场景：放款
            ApplyContractInfo contractInfo = applyContractInfoService.getOne(Wrappers.<ApplyContractInfo>query().lambda().eq(ApplyContractInfo::getApplyNo, condition.getApplyNo()));
            //step1:获取所有签约合同关联关系表数据
            if(YES.equals(contractInfo.getReappearFlag())){
                signRelationList = applySignRelationService.list(Wrappers.<ApplySignRelation>query().lambda()
                        .eq(ApplySignRelation::getBusinessNo,condition.getBusiNo()));
                if(signRelationList !=null && signRelationList.size()>0){
                    for(ApplySignRelation relation:signRelationList){
                        List<ComAttachmentFile> comAttachmentFileList = attachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                                .eq(ComAttachmentFile::getBusiNo, condition.getBusiNo())
                                .eq(ComAttachmentFile::getAttachmentCode,relation.getTempleId().toString()));
                        if(comAttachmentFileList !=null && comAttachmentFileList.size()>0){
                            for(ComAttachmentFile file :comAttachmentFileList){
                                Assert.isTrue(file!=null,"重出合同模板不存在");
                                creatContractService.contractSinglePrint(condition.getApplyNo(),file.getBusiNo(),file,condition.getServiceClientType());
                            }
                        }
                        relation.setStatus(NO);
                        relation.setUpdateTime(null);
                        applySignRelationService.updateById(relation);
                        ComPrintFormManage formManage = comPrintFormManageService.getOne(Wrappers.<ComPrintFormManage>query().lambda().eq(ComPrintFormManage::getId, relation.getTempleId().toString()));
                        if(formManage !=null){
                            List<ComAttachmentFile> fileList = attachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                                    .eq(ComAttachmentFile::getBusiNo, condition.getBusiNo())
                                    .eq(ComAttachmentFile::getAttachmentCode,formManage.getAscriptionSubClass()));
                            if(fileList !=null && fileList.size()>0){
                                for(ComAttachmentFile file :fileList){
                                    log.info("删除附件信息表对应模版数据"+file);
                                    attachmentFileService.removeById(file);
                                }
                            }
                        }
                    }
                }else{
                    return IResponse.fail("合同签约数据不存在，无法重出");
                }
                //step2:更新合同主表重出标识为：否
                if(contractInfo !=null){
                    contractInfo.setReappearFlag(NO);
                    applyContractInfoService.updateById(contractInfo);
                }
            }
        }else{
            //重出场景：进件：step:1判断，如果主表重出状态为是（1），则重出所有合同
            ApplyOrderInfo applyOrderInfo = applyOrderInfoService.getOne(Wrappers.<ApplyOrderInfo>query().lambda()
                    .eq(ApplyOrderInfo::getApplyNo, condition.getApplyNo()));
            if(YES.equals(applyOrderInfo.getReappearFlag())){
                signRelationList = applySignRelationService.list(Wrappers.<ApplySignRelation>query().lambda()
                        .eq(ApplySignRelation::getBusinessNo,condition.getBusiNo()));
                if(signRelationList !=null && signRelationList.size()>0){
                    for(ApplySignRelation relation:signRelationList){
                        List<ComAttachmentFile> comAttachmentFileList = attachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                                .eq(ComAttachmentFile::getBusiNo, condition.getBusiNo())
                                .eq(ComAttachmentFile::getAttachmentCode,relation.getTempleId().toString()));
                        if(comAttachmentFileList !=null && comAttachmentFileList.size()>0){
                            for(ComAttachmentFile file :comAttachmentFileList){
                                Assert.isTrue(file!=null,"重出合同模板不存在");
                                creatContractService.applySinglePrintByCustId(condition.getApplyNo(),file,condition.getServiceClientType());
                            }
                        }
                        relation.setStatus(NO);
                        relation.setUpdateTime(null);
                        applySignRelationService.updateById(relation);
                        ComPrintFormManage formManage = comPrintFormManageService.getOne(Wrappers.<ComPrintFormManage>query().lambda().eq(ComPrintFormManage::getId, relation.getTempleId().toString()));
                        if(formManage !=null){
                            List<ComAttachmentFile> fileList = attachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                                    .eq(ComAttachmentFile::getBusiNo, condition.getApplyNo())
                                    .eq(ComAttachmentFile::getAttachmentCode,formManage.getAscriptionSubClass()));
                            if(fileList !=null && fileList.size()>0){
                                for(ComAttachmentFile file :fileList){
                                    log.info("删除附件信息表对应模版数据"+file);
                                    attachmentFileService.removeById(file);
                                }
                            }
                        }
                    }
                }else{
                    return IResponse.fail("合同签约数据不存在，无法重出");
                }
                //step2:更新进件主表重出状态为：否
                applyOrderInfo.setReappearFlag(NO);
                applyOrderInfoService.updateById(applyOrderInfo);
                //step3:更新客户信息表角色重出状态为：否
                List<ApplyCustBaseInfo> infoList = applyCustBaseInfoService.list(Wrappers.<ApplyCustBaseInfo>query().lambda()
                        .eq(ApplyCustBaseInfo::getApplyNo, condition.getApplyNo()));
                if(infoList !=null && infoList.size()>0){
                    for(ApplyCustBaseInfo info :infoList){
                        info.setReappearFlag(NO);
                        applyCustBaseInfoService.updateById(info);
                    }
                }
                return IResponse.success("重出成功！！");
            }else{
                //step1:查询需要重出的所有角色并重出合同
                List<ApplyCustBaseInfo> infoList = applyCustBaseInfoService.list(Wrappers.<ApplyCustBaseInfo>query().lambda()
                        .eq(ApplyCustBaseInfo::getApplyNo, condition.getApplyNo())
                        .eq(ApplyCustBaseInfo::getReappearFlag,YES));
                if(infoList !=null && infoList.size()>0){
                    for(ApplyCustBaseInfo info :infoList){
                        signRelationList = applySignRelationService.list(Wrappers.<ApplySignRelation>query().lambda()
                                .eq(ApplySignRelation::getBusinessNo,condition.getBusiNo())
                                .eq(ApplySignRelation::getCustId,info.getId().toString()));
                        if(signRelationList !=null && signRelationList.size()>0){
                            for(ApplySignRelation relation:signRelationList){
                                List<ComAttachmentFile> comAttachmentFileList = attachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                                        .eq(ComAttachmentFile::getBusiNo, condition.getBusiNo())
                                        .eq(ComAttachmentFile::getAttachmentCode,relation.getTempleId().toString()));
                                if(comAttachmentFileList !=null && comAttachmentFileList.size()>0){
                                    for(ComAttachmentFile file :comAttachmentFileList){
                                        Assert.isTrue(file!=null,"重出合同模板不存在");
                                        creatContractService.applySinglePrintByCustId(condition.getApplyNo(),file,condition.getServiceClientType());
                                    }
                                }
                                relation.setStatus(NO);
                                relation.setUpdateTime(null);
                                applySignRelationService.updateById(relation);

                                ComPrintFormManage formManage = comPrintFormManageService.getOne(Wrappers.<ComPrintFormManage>query().lambda().eq(ComPrintFormManage::getId, relation.getTempleId().toString()));
                                if(formManage !=null){
                                    List<ComAttachmentFile> fileList = attachmentFileService.list(Wrappers.<ComAttachmentFile>query().lambda()
                                            .eq(ComAttachmentFile::getBusiNo, condition.getApplyNo())
                                            .eq(ComAttachmentFile::getAttachmentCode,formManage.getAscriptionSubClass()));
                                    if(fileList !=null && fileList.size()>0){
                                        for(ComAttachmentFile file :fileList){
                                            log.info("删除附件信息表对应模版数据"+file);
                                            attachmentFileService.removeById(file);
                                        }
                                    }
                                }
                            }
                        }else{
                            return IResponse.fail("合同签约数据不存在，无法重出");
                        }
                        //step2:更新客户信息表重出状态为：否
                        info.setReappearFlag(NO);
                        applyCustBaseInfoService.updateById(info);
                    }
                    //step3:更新进件主表重出状态为：否
                    applyOrderInfo.setReappearFlag(NO);
                    applyOrderInfoService.updateById(applyOrderInfo);
                }
            }
        }

        return IResponse.success("重出成功！！");
    }

    /**
     * 进件征信授权书生成
     *
     * @param condition
     * @return
     */
    @PostMapping("/applyAuthorBatchPrint")
    @Transactional(rollbackFor = Exception.class)
    public IResponse applyAuthorBatchPrint(@RequestBody ComAttachmentCondition condition) {

        List<ComAttachmentFile> fileList = creatContractService.applyAuthorBatchPrint(condition.getBusinessType(),condition.getApplyNo(),condition.getCertNo(),condition.getServiceClientType());
        return IResponse.success(fileList);
    }

    /**
     * 预审批-批量合同模板
     *
     * @param condition
     * @return
     */
    @PostMapping("/preAuthorBatchPrint")
    @Transactional(rollbackFor = Exception.class)
    public IResponse preAuthorBatchPrint(@RequestBody ComAttachmentCondition condition) {

        List<ComAttachmentFile> fileList = creatContractService.preAuthorBatchPrint(condition.getBusinessType(),condition.getId(),condition.getServiceClientType());
        return IResponse.success(fileList);
    }

    /**
     * 预审批-单个模板重出
     * @param condition
     * @return
     */
    @PostMapping("/preAuthorSinglePrint")
    @Transactional(rollbackFor = Exception.class)
    public IResponse preAuthorSinglePrint(@RequestBody ComAttachmentCondition condition){

        ComAttachmentFile attachmentFile = comAttachmentFileService.getById(condition.getId());
        Assert.isTrue(attachmentFile!=null,"重出合同模板不存在");
        ComAttachmentFile comAttachmentFile = creatContractService.preAuthorSinglePrint(condition.getBusinessType(),attachmentFile.getBusiNo(),attachmentFile,condition.getServiceClientType());
        return IResponse.success(comAttachmentFile);
    }

    /**
     * 单个文件下载
     *
     * @param response
     * @param condition
     */
    @PostMapping("/downloadSingleFile")
    @Transactional(rollbackFor = Exception.class)
    public void downloadSingleFile(HttpServletResponse response, @RequestBody ComAttachmentCondition condition) {

        ComAttachmentFile attachmentFile = comAttachmentFileService.getById(condition.getId());
        byte[] fileByte = comAttachmentFileService.downloadAttachmentFile(attachmentFile);
        BufferedInputStream bufferedInputStream = null;
        try {
            response.reset(); // 重点突出
            if (fileByte.length > 0) {
                bufferedInputStream = new BufferedInputStream(IoUtil.toStream(fileByte));
                response.setContentType("multipart/form-data");
                response.setHeader("Content-Disposition", "attachment;filename=" + HttpUtil.encodeUtf8(attachmentFile.getFileName()));
                IoUtil.copy(bufferedInputStream, response.getOutputStream(), 1024);
                response.getOutputStream().flush();
                IoUtil.close(bufferedInputStream);
                return;
            }
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
        } catch (Exception e) {
            IoUtil.close(bufferedInputStream);
            log.error("文件下载失败:" + e.getMessage());
        } finally {
            IoUtil.close(bufferedInputStream);
        }
    }

    /**
     * 批量文件下载
     *
     * @param response
     * @param condition
     */
    @PostMapping("downloadBatchFile")
    public void downloadBatchFile(HttpServletResponse response, @RequestBody AttachmentListCondition condition) {

        // 1-临时目录
        String applyNo = condition.getApplyNo();
        String destPath = fileProperties.getTempDir() + File.separator + applyNo + File.separator + DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomNumber();
        // 2-远程下载
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", comAttachmentFileService.getAuthorization());
        for (ComAttachmentFile attachmentFile : condition.getAttachmentList()) {
            ComAttachmentFile comAttachmentFile = comAttachmentFileService.getById(attachmentFile.getId());
            byte[] fileByte = comAttachmentFileService.downloadAttachmentFile(comAttachmentFile);
            if (fileByte.length > 0) {
                FileUtil.writeBytes(fileByte, destPath + File.separator + attachmentFile.getFileName());
            }
        }
        BufferedInputStream bufferedInputStream = null;
        try {
            String zipFileName = UUID.randomUUID().toString() + ".zip";
            File zipFile = ZipUtil.zip(destPath);
            response.reset(); // 重点突出
            if (FileUtil.exist(destPath)) {
                File file = FileUtil.file(zipFile);
                bufferedInputStream = FileUtil.getInputStream(file);
                response.setContentType("multipart/form-data");
                response.setHeader("Content-Disposition", "attachment;filename=" + HttpUtil.encodeUtf8(zipFileName));
                IoUtil.copy(bufferedInputStream, response.getOutputStream(), 1024);
                response.getOutputStream().flush();
                IoUtil.close(bufferedInputStream);
                //删除打包文件
                FileUtil.del(destPath);
                return;
            }
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
        } catch (Exception e) {
            IoUtil.close(bufferedInputStream);
            FileUtil.del(destPath);
            log.error("文件下载失败:" + e.getMessage());
        } finally {
            IoUtil.close(bufferedInputStream);
        }
    }

}
